
using System.Text.Json;
using CliWrap;
using CliWrap.Buffered;
using Ke.Bee.Shared.Abstractions;
using Ke.Bee.Shared.Models.Multimedias;
using Microsoft.Extensions.Options;

/// <summary>
/// FFprobe 音频格式检查器
/// </summary>
public class FFprobeAudioFormatChecker : IAudioFormatChecker
{
    private readonly JsonSerializerOptions _jsonSerializerOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    private readonly FFmpegOptions _ffmpegOptions;

    public FFprobeAudioFormatChecker(IOptions<FFmpegOptions> options)
    {
        if (!File.Exists(options.Value.FFprobePath))
        {
            throw new FileNotFoundException(options.Value.FFprobePath);
        }

        _ffmpegOptions = options.Value;
    }

    /// <summary>
    /// 检查音频文件是否符合要求
    /// </summary>
    /// <param name="filePath"></param>
    /// <returns></returns>
    public async Task<AudioFormatInfo> CheckAudioFormatAsync(string filePath)
    {
        var info = new AudioFormatInfo { FilePath = filePath };

        try
        {
            // 使用 ffprobe 获取详细的音频信息
            var result = await Cli.Wrap(_ffmpegOptions.FFprobePath)
                .WithArguments(args => args
                    .Add("-v")
                    .Add("quiet")
                    .Add("-print_format")
                    .Add("json")
                    .Add("-show_streams")
                    .Add("-show_format")
                    .Add("-select_streams")
                    .Add("a")  // 只选择音频流
                    .Add(filePath)
                )
                .WithValidation(CommandResultValidation.None)
                .ExecuteBufferedAsync()
                ;

            if (result.ExitCode != 0)
            {
                info.IsValid = false;
                info.ErrorMessage = $"FFprobe 执行失败: {result.StandardError}";
                return info;
            }

            // 使用 System.Text.Json 解析输出
            info = await ParseFFprobeOutput(result.StandardOutput, filePath);

            return info;
        }
        catch (Exception ex)
        {
            info.IsValid = false;
            info.ErrorMessage = $"检查音频格式时发生错误: {ex.Message}";
            return info;
        }
    }

    private async Task<AudioFormatInfo> ParseFFprobeOutput(string output, string filePath)
    {
        var info = new AudioFormatInfo { FilePath = filePath };

        try
        {
            if (string.IsNullOrEmpty(output))
            {
                info.IsValid = false;
                info.ErrorMessage = "FFprobe 没有返回任何信息";
                return info;
            }

            // 使用 System.Text.Json 解析 JSON 输出
            var ffprobeOutput = JsonSerializer.Deserialize<FFprobeOutput>(output, _jsonSerializerOptions);

            // 检查是否有音频流
            if (ffprobeOutput?.Streams == null || ffprobeOutput.Streams.Length == 0)
            {
                info.IsValid = false;
                info.ErrorMessage = "文件中没有找到音频流";
                return info;
            }

            // 获取第一个音频流（通常只有一个）
            var audioStream = ffprobeOutput.Streams[0];

            // 提取音频信息
            info.Codec = audioStream.Codec_Name ?? "未知";
            info.Format = ffprobeOutput.Format?.Format_Name ?? "未知";

            if (int.TryParse(audioStream.Sample_Rate, out int sampleRate))
                info.SampleRate = sampleRate;

            info.Channels = audioStream.Channels;
            info.SampleFormat = audioStream.Sample_Fmt ?? "未知";
            info.BitDepth = audioStream.Bits_Per_Sample ?? "未知";

            // 解析时长
            if (double.TryParse(audioStream.Duration ?? ffprobeOutput.Format?.Duration, out double durationSeconds))
                info.Duration = TimeSpan.FromSeconds(durationSeconds);

            // 检查是否符合要求：16kHz 单声道 PCM S16LE WAV
            info.IsValid = info.Codec == "pcm_s16le" &&
                          info.SampleRate == 16000 &&
                          info.Channels == 1 &&
                          (info.Format.Contains("wav") || info.Format.Contains("WAV"));

            if (!info.IsValid)
            {
                var actualFormat = $"{info.Codec}, {info.SampleRate}Hz, {info.Channels}声道";
                var expectedFormat = "pcm_s16le, 16000Hz, 1声道, WAV格式";
                info.ErrorMessage = $"音频格式不符合要求。\n实际: {actualFormat}\n期望: {expectedFormat}";
            }

            return info;
        }
        catch (JsonException jsonEx)
        {
            info.IsValid = false;
            info.ErrorMessage = $"解析 FFprobe JSON 输出时发生错误: {jsonEx.Message}";
            return info;
        }
        catch (Exception ex)
        {
            info.IsValid = false;
            info.ErrorMessage = $"处理音频信息时发生错误: {ex.Message}";
            return info;
        }
    }
    
    /// <summary>
    /// 检查音频是否符合 16kHz 单声道 PCM S16LE WAV 格式
    /// </summary>
    public async Task<bool> IsValidFormatAsync(string filePath)
    {
        var info = await CheckAudioFormatAsync(filePath);
        return info.IsValid;
    }

    /// <summary>
    /// 批量检查多个音频文件
    /// </summary>
    public async Task<Dictionary<string, AudioFormatInfo>> CheckMultipleFilesAsync(IEnumerable<string> filePaths)
    {
        var results = new Dictionary<string, AudioFormatInfo>();

        foreach (var filePath in filePaths)
        {
            results[filePath] = await CheckAudioFormatAsync(filePath);
        }

        return results;
    }
}